using System;
using UnityEngine;
using MinesweeperPlus.Scripts.Abstractions.Enums;
using MinesweeperPlus.Scripts.Configs;
using MinesweeperPlus.Scripts.Objects.Advertisements;

namespace MinesweeperPlus.Scripts.Objects
{
    public sealed class Game : MonoBehaviour
    {
        #region Constants
        private const string GAME_DATA_FILE_NAME = "/GameData.pdat";

        private const float TIMER_INTERVAL_IN_SECONDS = 1;
        #endregion

        #region Actions
        public Action<float> OnUpdate;
        public Action<float> OnFixedUpdate;
        #endregion

        #region Variables
        [SerializeField] private GameConfig _config;

        private Ads _ads;
        private InterstitialAds _interstitialAds;
        private RewardedAds _rewardedAds;
        private PlayerCamera _playerCamera;
        private GameData _gameData;
        private Playfield _playfield;
        private Timer _timer;
        private PlayerInput _playerInput;
        private UI _ui;
        #endregion

        #region Unity Methods
        private void Start()
        {
            InitGameData();
            InitAds();
            InitInterstitialAds();
            InitRewardedAds();
            InitTimer();
            InitPlayerCamera();
            InitPlayerInput();
            InitPlayfield();
            InitUI();

            OnUpdate += (_) =>
            {
                if (Input.GetKeyDown(KeyCode.UpArrow))
                    _gameData.Money += 100;
            };
        }

        private void Update() => OnUpdate?.Invoke(Time.deltaTime);
        private void FixedUpdate() => OnFixedUpdate?.Invoke(Time.deltaTime);
        #endregion

        #region Other Methods
        private void InitAds()
        {
            _ads = new();
        }
        private void InitInterstitialAds()
        {
            _interstitialAds = new();
        }
        private void InitRewardedAds()
        {
            _rewardedAds = new();
            _rewardedAds.LoadAds();
        }
        private void InitPlayerCamera()
        {
            _playerCamera = new(Camera.main);
        }
        private void InitGameData()
        {
            _gameData = new(Application.persistentDataPath + GAME_DATA_FILE_NAME);
        }
        private void InitTimer()
        {
            _timer = new(this, TIMER_INTERVAL_IN_SECONDS);
        }
        private void InitPlayerInput()
        {
            _playerInput = new PlayerInput(this);
        }
        private void InitPlayfield()
        {
            _playfield = new(
                _config.PlayfieldConfig, 
                _playerCamera, 
                _playerInput,
                _gameData);
        }
        private void InitUI()
        {
            _ui = new(
                _config.UIConfig, 
                _playerCamera, 
                _playfield,
                _timer, 
                _gameData,
                _interstitialAds,
                _rewardedAds);
        }
        #endregion
    }
}
